﻿using System.Collections;
using UnityEngine;
using ObjectPool;

public class DashController : ActionController
{
    private ObjectManager objectManager;

    public float DashSpeed { get; private set; }

    private float counter_dash;         //冲刺计时器
    private Coroutine co_dash;          //冲刺协程

    private float t_dash;               //冲刺持续时间
    private float t_shoot = 0.1f;       //冲刺冷却时间
    private bool b_canShoot = true;     //冲刺是否冷却完毕

    protected override void OnStart()
    {
        objectManager = Service.Get<ObjectManager>();
        DashSpeed = 20f; 
        t_dash = 0.15f;

        eventSystem.CollidePlatform += OnCollide;
        eventSystem.CameraMove += OnCameraMove;
    }

    private void OnCollide(Vector2 normalLine, GameObject platform, Character player)
    {
        audioPlayer.CreateAudio("AudioSource/fx_collide");
        objectManager.Activate(EObject.CollideEffect, transform.position, normalLine.ToAngle());
        if(!player.Grounded)
            player.Energy += 2;
        StartCoroutine(RestartDash());
    }
    private void OnCameraMove(bool start)
    {
        if (start)
        {
            m_rigidbody.velocity = Vector2.zero;
            DashEnd();
        }
    }

    private void FixedUpdate()
    {
        if(player.b_wantDash)
        {
            Dash();
            player.b_wantDash = false;
        }
    }

    public void Dash()
    {
        audioPlayer.CreateAudio("AudioSource/fx_dash");

        if (!b_canShoot || player.Energy == 0)
            return;

        player.Energy--;

        if (co_dash != null)
            StopCoroutine(co_dash);
        co_dash = StartCoroutine(Dash(-player.drct_aim, t_dash));

        StartCoroutine(ShootCoolDown());
    }

    private IEnumerator ShootCoolDown()
    {
        b_canShoot = false;
        yield return new WaitForSeconds(t_shoot);
        b_canShoot = true;
    }

    //冲刺时不能主动移动，也不受重力影响
    public IEnumerator Dash(Vector2 direction, float t)
    {
        counter_dash = 0;
        player.b_isDashing = true;
        m_rigidbody.gravityScale = 0;
        m_rigidbody.velocity = direction * DashSpeed;
        for (; counter_dash < t; counter_dash += Time.fixedDeltaTime)
        {
            objectManager.Activate(EObject.Afterimage_Player, transform.position,0f);
            yield return new WaitForFixedUpdate();
        }
        //减速过程，时间很短
        for (; m_rigidbody.velocity.magnitude > player.MaxHorizontalSpeed;)
        {
            m_rigidbody.velocity -= m_rigidbody.velocity.normalized * 2f;
            yield return new WaitForFixedUpdate();
        }
        DashEnd();
    }
    public void DashEnd()
    {
        if (player.b_isDashing && co_dash != null)
            StopCoroutine(co_dash);
        player.b_isDashing = false;
        m_rigidbody.gravityScale = 1;
    }
    //重启冲刺，用于撞击平台后进行反方向时间更短的冲刺，效果上看，撞击平台不会打断冲刺，且冲刺总时间会略微延长
    public IEnumerator RestartDash()
    {
        DashEnd();
        //等待物理状态更新，反弹后速度的方向即为冲刺方向
        yield return new WaitForFixedUpdate();
        if (t_dash - counter_dash > 0)
            co_dash = StartCoroutine(Dash(m_rigidbody.velocity.normalized, t_dash - counter_dash + 0.03f));
    }
}
